/*  
 * Copyright (c) 2009  Christian Riekoff <info@texone.org>  
 *  
 *  This file is free software: you may copy, redistribute and/or modify it  
 *  under the terms of the GNU General Public License as published by the  
 *  Free Software Foundation, either version 2 of the License, or (at your  
 *  option) any later version.  
 *  
 *  This file is distributed in the hope that it will be useful, but  
 *  WITHOUT ANY WARRANTY; without even the implied warranty of  
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
 *  General Public License for more details.  
 *  
 *  You should have received a copy of the GNU General Public License  
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
 *  
 * This file incorporates work covered by the following copyright and  
 * permission notice:  
 */
package cc.creativecomputing.timeline;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cc.creativecomputing.CCApp;
import cc.creativecomputing.control.CCBooleanControl;
import cc.creativecomputing.control.CCExternalController;
import cc.creativecomputing.control.CCFloatControl;
import cc.creativecomputing.control.CCIntegerControl;
import cc.creativecomputing.control.CCValueControl;
import cc.creativecomputing.timeline.model.TrackType;
import cc.creativecomputing.timeline.model.communication.TimelineConnector;
import cc.creativecomputing.timeline.view.TimelineContainer;

/**
 * @author christianriekoff
 *
 */
public class CCUITimelineConnector extends TimelineConnector implements CCExternalController {
	
	private HashMap<String, CCValueControl<?>> _myControlMap = new HashMap<String, CCValueControl<?>>();
	
	private Map<String, CCTimedEventListener> _myTimedEventListener = new HashMap<String, CCTimedEventListener>();
	public CCUITimelineConnector(CCApp theApp, TimelineContainer theTimelineContainer) {
		super(theTimelineContainer);
		theApp.ui().addExternalController(this);
	}
	
	/* (non-Javadoc)
	 * @see de.artcom.timeline.CommunicationLayer#getObjectNames()
	 */
	public Collection<String> getObjectNames() {
		List<String> myResult = new ArrayList<String>();
		myResult.addAll(_myControlMap.keySet());
		myResult.addAll(_myTimedEventListener.keySet());
		return myResult;
	}
	
	/* (non-Javadoc)
	 * @see de.artcom.timeline.CommunicationLayer#sendValue(java.lang.String, double)
	 */
	@Override
	public void sendDoubleValue(String theAddress, double theValue) {
		CCFloatControl myControl = (CCFloatControl)_myControlMap.get(theAddress);
		if (myControl != null) {
			myControl.element().changeValue((float)theValue);
		}
	}
	
	/* (non-Javadoc)
	 * @see de.artcom.timeline.model.communication.CommunicationLayer#sendIntegerValue(java.lang.String, int)
	 */
	@Override
	public void sendIntegerValue(String theAddress, int theValue) {
		CCIntegerControl myControl = (CCIntegerControl)_myControlMap.get(theAddress);
		if (myControl != null) {
			myControl.element().changeValue(theValue);
		}
	}
	
	/* (non-Javadoc)
	 * @see de.artcom.timeline.model.communication.CommunicationLayer#sendBooleanValue(java.lang.String, boolean)
	 */
	@Override
	public void sendBooleanValue(String theAddress, boolean theValue) {
		CCBooleanControl myControl = (CCBooleanControl)_myControlMap.get(theAddress);
		if (myControl != null) {
			myControl.element().changeValue(theValue);
		}
	}
	
	@Override
	public void sendStringValue(String theAddress, String theValue) {
		
	}
	
	
	
	public double currentValue(final String theAddress) {
		CCValueControl<?> myControl = _myControlMap.get(theAddress);
		if(myControl instanceof CCBooleanControl) {
			CCBooleanControl myBooleanControl = (CCBooleanControl)myControl;
			if(myBooleanControl.element().value()) return 1;
			else return 0;
		}
		if(myControl instanceof CCFloatControl) {
			CCFloatControl myFloatControl = (CCFloatControl)myControl;
			return myFloatControl.element().value();
		}
		if(myControl instanceof CCIntegerControl) {
			CCIntegerControl myIntControl = (CCIntegerControl)myControl;
			return myIntControl.element().value();
		}
		return 0;
	}
	

	/* (non-Javadoc)
	 * @see cc.creativecomputing.control.CCUIExternalController#addControl(java.lang.String, java.lang.String, cc.creativecomputing.control.controls.CCUIValueControl)
	 */
	@Override
	public <ValueType> void addControl(
		String theTabName, 
		String theObjectID,
		CCValueControl<ValueType> theControl
	) {
		if(theControl.external()) {
			String myKey = "/" + theTabName + "/" + theObjectID + "/" + theControl.name();
			_myControlMap.put(myKey, theControl);
			
			TrackType myTrackType = TrackType.DOUBLE;
			
			if(theControl instanceof CCFloatControl) {
				myTrackType = TrackType.DOUBLE;
			}
			if(theControl instanceof CCIntegerControl) {
				myTrackType = TrackType.INTEGER;
			}
			if(theControl instanceof CCBooleanControl) {
				myTrackType = TrackType.BOOLEAN;
			}
			
			_myTimelineContainer.addCurveTrack("/" + theTabName + "/" + theObjectID, theControl.name(), myTrackType, theControl.min(),theControl.max());
		}
	}
}
